/******************************************************
Cours:   LOG121
Session: A2013
Groupe:  04
Projet: Laboratoire #4
Étudiant(e)s: Fredy Alexander Bonilla, Renaud Vincent, Simon Castro
                            
Professeur : Francis Cardinal
Nom du fichier: Controleur.java
Date créé: 2013-11-22
Date dern. modif. 2013-12-04
*******************************************************
Historique des modifications
*******************************************************
* Ajout des methodes appeles par les observeurs
*******************************************************/ 

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import javax.swing.JFrame;
import javax.swing.JOptionPane;
/**
 * La classe Controleur recoit les notification de la vue selon le patron MVC. 
 * Elle contient la methode actionPerformed qui creer une commande en utilisant
 * la fabrique selon un evenement envoye par la Vue. 
 * 
 * @author Simon
 * @author Fredy
 *
 */
public class Controleur{

	//Atributs
	private int tabIndexCourant;
	private Modele modele;
	//Chemin sauvegarde sert a garder en memoire le chemin d'acces a une image
	private String cheminSauvegarde;
	
	/**
	 * Constructeur de la classe Controleur, se liant au Modele.
	 * @param modele
	 */
	public Controleur(Modele modele){
		this.modele = modele;
	}

	/**
	 * Cette methode recoit en paramettre les parametre des actions effectue 
	 * par l'utilisateur. Elle envoie par la suite la commande pour lajouter 
	 * dans la sauvegarde memento et envoie les modifications au gestionnaire.
	 * @param modif
	 */
	public void activerCommande(Modifications modif){
		CommandInvoker.getCommande().ajouterMemento(new Etat(modele.getPerspectiveAt(tabIndexCourant).creerMemento(), this.tabIndexCourant));
		CommandInvoker.getCommande().ajouterExecuter(modif);
	}
	
	/**
	 * REDO
	 */
	public void refaireCommande(){
		CommandInvoker.getCommande().refaireCommande();
	}
	
	/**
	 * UNDO
	 */
	public void defaireCommande(){
		CommandInvoker.getCommande().annulerModification(this.modele.getPerspectiveAt(tabIndexCourant));
	}
	
	/**
	 * Cette methode envoie recoit un indice indiquant de quel zoom il s'agit et 
	 * envoie instancie un object modifications avec les parametre du zoom, avec
	 * la methode activerCommande
	 * @param indice
	 */
	public void zoom(int indice){
		this.activerCommande(new Modifications(this.modele.getPerspectiveAt(this.tabIndexCourant), "zoom", indice, 0, 0));
	}
	
	/**
	 * Methode qui recoit l'index de l'onglet courant
	 * @return l'index de la tab active
	 */
	public int getTabIndexCourrant() {
		return this.tabIndexCourant;
	}
	
	/**
	 * Methode qui mute l'index courant de l'onglet
	 * 
	 * @param index
	 */
	public void setTabIndexCourant(int index){
		this.tabIndexCourant = index;
	}
	
	/**
	 * Methode qui appel l'activateur de commande du gestionnaire pour en creer 
	 * une translation
	 * 
	 * @param xT
	 * @param yT
	 */
	public void translation(int xT, int yT){
		this.activerCommande(new Modifications(this.modele.getPerspectiveAt(this.tabIndexCourant),"translation", 0, xT,yT));
	}
	
	/**
	 * Methode appelee par le menu "nouvelle image". Modifie l'image
	 * du modele.
	 * @param fichier Un fichier charge depuis le JFileChooser
	 */
	public void changerImage(File fichier){
		this.modele.getImage().setImage(fichier);
		CommandInvoker.getCommande().reset();
	}
	
	/**
	 * Methode appelee par le menu "sauvegarder". Serialise les perspective
	 * des deux tabs dans des fichiers separes nommes par l'utilisateur.
	 */
	public void sauvegarde() {
		try {
			//Serialisation de la perspective 1
			ObjectOutputStream fluxSortieTab1 = 
					new ObjectOutputStream(
							new FileOutputStream(JOptionPane.showInputDialog(new JFrame(),"Sauvegarder perspective 1 sous:")));
			fluxSortieTab1.writeObject(modele.getPerspectiveAt(this.tabIndexCourant));
			//fluxSortie.writeObject(modele.getImage());
			fluxSortieTab1.close();
			
			//Serialisation de la perspective 2
			ObjectOutputStream fluxSortieTab2 = 
					new ObjectOutputStream(
							new FileOutputStream(JOptionPane.showInputDialog(new JFrame(),"Sauvegarder perspective 2 sous:")));
			//La tab active est la premiere (on sauvegarde donc la perspective sur la deuxime)
			if (tabIndexCourant == 0) 
				fluxSortieTab2.writeObject(modele.getPerspectiveAt(this.tabIndexCourant + 1));
			//La tab active est la seconde (donc on sauvegarde la tab active)
			else
				fluxSortieTab2.writeObject(modele.getPerspectiveAt(this.tabIndexCourant));
			fluxSortieTab2.close();
			
			//Sauvegarde du chemin actuel en memoire dans l'attribut
			cheminSauvegarde = modele.getImage().getChemin();
		} 
		catch (FileNotFoundException e1) {
			e1.printStackTrace();
		} 
		catch (IOException e1) {
			e1.printStackTrace();
		}
	}
	
	/**
	 * Methode d'ouverture d'un fichier
	 * @param fichier
	 */
	public void ouvrir(File fichier) {
		
		try {
			FileInputStream fluxFichier = new FileInputStream(fichier);
			@SuppressWarnings("resource")
			ObjectInputStream fluxOuverture = new ObjectInputStream(fluxFichier);
			Object objetOuvert = fluxOuverture.readObject();
			Perspective p = (Perspective)objetOuvert;
			modele.getPerspectiveAt(this.tabIndexCourant).copier(p);
			modele.getImage().setImage(new File(cheminSauvegarde));
			CommandInvoker.getCommande().reset();
			
		} 
		catch (FileNotFoundException e) {
			e.printStackTrace();
		} 
		catch (IOException e) {
			e.printStackTrace();
		} 
		catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		
	}
}
